# gomoku_ai/utils/visual_board.py
import pygame
import sys
import numpy as np


class VisualBoard:
    def __init__(self, board_size):
        pygame.init()
        pygame.font.init()

        self.board_size = board_size

        # 窗口和棋盘设置
        self.window_size = 800
        self.board_margin = 50
        self.grid_size = 60  # 初始值，会被 _update_layout 重新计算
        self.piece_radius = 28  # 初始值，会被 _update_layout 重新计算

        # 颜色定义
        self.BACKGROUND_COLOR = (220, 179, 92)  # 棋盘背景色
        self.LINE_COLOR = (0, 0, 0)  # 线条颜色
        self.BLACK_COLOR = (0, 0, 0)  # 黑棋颜色
        self.WHITE_COLOR = (255, 255, 255)  # 白棋颜色
        self.LAST_MOVE_COLOR = (255, 0, 0)  # 最后一手标记颜色
        self.TEXT_COLOR = (50, 50, 50)  # 文字颜色

        # --- 关键修改：允许窗口调整大小 ---
        self.screen = pygame.display.set_mode((self.window_size, self.window_size), pygame.RESIZABLE)
        pygame.display.set_caption("五子棋 AI")

        # 字体
        self.font = pygame.font.SysFont('simhei', 24)
        self.info_font = pygame.font.SysFont('simhei', 20)

        self.last_move = None
        self._update_layout()  # 初始化时计算一次布局

    def _update_layout(self):
        """根据当前窗口大小更新布局参数"""
        width, height = self.screen.get_width(), self.screen.get_height()
        # 使用较小的边作为棋盘的有效区域，以适应非正方形窗口
        effective_size = min(width, height)

        # 动态计算边距和格子大小
        self.board_margin = effective_size // 10
        self.grid_size = (effective_size - 2 * self.board_margin) // (self.board_size - 1)
        self.piece_radius = max(10, self.grid_size // 2 - 2)  # 确保棋子不会太小

    def handle_resize(self, event):
        """处理窗口大小改变事件"""
        self.screen = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)
        self._update_layout()

    def update(self, board, game_result, current_player, info_text=""):
        """更新整个棋盘显示"""
        self.screen.fill(self.BACKGROUND_COLOR)

        # 计算棋盘在窗口中的偏移量，使其居中
        width, height = self.screen.get_width(), self.screen.get_height()
        board_pixel_size = (self.board_size - 1) * self.grid_size
        offset_x = (width - board_pixel_size) // 2
        offset_y = (height - board_pixel_size) // 2

        # 绘制棋盘网格
        for i in range(self.board_size):
            # 横线
            start_pos = (offset_x, offset_y + i * self.grid_size)
            end_pos = (offset_x + board_pixel_size, offset_y + i * self.grid_size)
            pygame.draw.line(self.screen, self.LINE_COLOR, start_pos, end_pos, 2)
            # 竖线
            start_pos = (offset_x + i * self.grid_size, offset_y)
            end_pos = (offset_x + i * self.grid_size, offset_y + board_pixel_size)
            pygame.draw.line(self.screen, self.LINE_COLOR, start_pos, end_pos, 2)

        # 绘制棋子
        for r in range(self.board_size):
            for c in range(self.board_size):
                if board[r, c] != 0:
                    color = self.BLACK_COLOR if board[r, c] == 1 else self.WHITE_COLOR
                    center = (offset_x + c * self.grid_size, offset_y + r * self.grid_size)
                    pygame.draw.circle(self.screen, color, center, self.piece_radius)

        # 标记最后一手
        if self.last_move:
            r, c = self.last_move
            center = (offset_x + c * self.grid_size, offset_y + r * self.grid_size)
            pygame.draw.circle(self.screen, self.LAST_MOVE_COLOR, center, 5)

        # 显示信息文本
        info_surface = self.info_font.render(info_text, True, self.TEXT_COLOR)
        self.screen.blit(info_surface, (10, 10))

        # 如果游戏结束，显示获胜信息
        if game_result != 0:
            winner_text = "黑棋获胜！" if game_result == 1 else "白棋获胜！"
            if game_result == 0.1:
                winner_text = "平局！"

            # 创建半透明背景
            overlay = pygame.Surface((width, 60))
            overlay.set_alpha(200)
            overlay.fill((255, 255, 255))
            self.screen.blit(overlay, (0, height // 2 - 30))

            # 显示获胜文字
            win_surface = self.font.render(winner_text, True, self.BLACK_COLOR)
            win_rect = win_surface.get_rect(center=(width // 2, height // 2))
            self.screen.blit(win_surface, win_rect)

        pygame.display.flip()

    def get_human_move(self, board):
        """获取人类玩家的鼠标点击输入"""
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.close()
                    sys.exit()
                if event.type == pygame.MOUSEBUTTONDOWN:
                    x, y = event.pos

                    # 计算棋盘偏移量
                    width, height = self.screen.get_width(), self.screen.get_height()
                    board_pixel_size = (self.board_size - 1) * self.grid_size
                    offset_x = (width - board_pixel_size) // 2
                    offset_y = (height - board_pixel_size) // 2

                    # 将像素坐标转换为棋盘坐标
                    col = round((x - offset_x) / self.grid_size)
                    row = round((y - offset_y) / self.grid_size)

                    # 检查坐标是否在有效范围内
                    if 0 <= row < self.board_size and 0 <= col < self.board_size:
                        if board[row, col] == 0:
                            return row * self.board_size + col
        return None

    def set_last_move(self, move):
        """设置最后一手棋的坐标"""
        self.last_move = move

    def close(self):
        """关闭Pygame"""
        pygame.quit()
